package com.hxd.otc.module.my.activity;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import com.hxd.otc.R;
import com.hxd.otc.base.BaseActivity;
import com.hxd.otc.common.UserHelper;
import com.hxd.otc.dialog.ExchangeSymbolPopupWindow;
import com.hxd.otc.module.my.bean.ExchangeRecordBean;
import com.hxd.otc.module.my.bean.ExchangeRuleBean;
import com.hxd.otc.module.my.contract.ExchangeContract;
import com.hxd.otc.module.my.presenter.ExchangePresenter;
import com.hxd.otc.other.CustomBounceTopEnter;
import com.hxd.otc.other.SlideTopExit;
import com.hxd.otc.utils.DataUtils;
import com.hxd.otc.utils.ResourceUtil;
import com.hxd.otc.utils.StringUtil;
import com.hxd.otc.widget.LimitNumberTextWatcher;
import com.hxd.otc.widget.TitleBar;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * Created by lzy on 2018/12/26 0026.
 * description ${兑换}
 */
public class ExchangeActivity extends BaseActivity<ExchangePresenter> implements ExchangeContract.IView {
    @BindView(R.id.title_bar)
    TitleBar mTitleBar;
    @BindView(R.id.tv_out)
    TextView mTvOut;
    @BindView(R.id.et_out)
    EditText mEtOut;
    @BindView(R.id.tv_in)
    TextView mTvIn;
    @BindView(R.id.et_in)
    EditText mEtIn;
    @BindView(R.id.tv_exchange_rate)
    TextView mTvExchangeRate;
    @BindView(R.id.tv_service_charge)
    TextView mTvServiceCharge;
    @BindView(R.id.tv_change_the_quantity)
    TextView mTvChangeTheQuantity;
    @BindView(R.id.tv_confirm)
    TextView mTvConfirm;
    @BindView(R.id.tv_exchange_explain)
    TextView mTvExchangeExplain;

    private LimitNumberTextWatcher mOutWatcher;
    private LimitNumberTextWatcher mInWatcher;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_exchange;
    }

    @Override
    protected ExchangePresenter createPresenter() {
        return new ExchangePresenter(this);
    }

    @Override
    protected void initView() {
    }

    @Override
    protected void initData() {
        mPresenter.exchangeCoinRule();
    }

    @Override
    protected void initEvent() {
        mOutWatcher = new LimitNumberTextWatcher(mEtOut, 9, 8) {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                //先移除输入监听
                mEtOut.removeTextChangedListener(mOutWatcher);
                mEtIn.removeTextChangedListener(mInWatcher);
                //进行小数输入限制
                super.onTextChanged(s, start, before, count);
                //通过转出币种数量更新转入币种数量
                updateInNumsByOutNums();
                //重新添加输入监听
                mEtOut.addTextChangedListener(mOutWatcher);
                mEtIn.addTextChangedListener(mInWatcher);
                //更新手续费
                updateFee();
            }
        };

        mInWatcher = new LimitNumberTextWatcher(mEtIn, 9, 8) {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                //先移除输入监听
                mEtOut.removeTextChangedListener(mOutWatcher);
                mEtIn.removeTextChangedListener(mInWatcher);
                //进行小数输入限制
                super.onTextChanged(s, start, before, count);
                //通过转入币种数量更新转出币种数量
                updateOutNumsByInNums();
                //重新添加输入监听
                mEtOut.addTextChangedListener(mOutWatcher);
                mEtIn.addTextChangedListener(mInWatcher);
                //更新手续费
                updateFee();
            }
        };

        mEtOut.addTextChangedListener(mOutWatcher);
        mEtIn.addTextChangedListener(mInWatcher);

        mTitleBar.setOnTitleBarItemClickListener(new TitleBar.OnTitleBarItemClickListener() {
            @Override
            public void onBack(View v) {

            }

            @Override
            public void onRight(View v) {

                $startActivity(ExchangeRecoderActivity.class);
            }
        });
    }

    /**
     * 通过转出币种数量更新转入币种数量
     */
    private void updateInNumsByOutNums() {
        String outSymbol = getOutSymbol();
        String inSymbol = getInSymbol();
        //当兑换信息不正常时则重新拉取兑换信息
        if (TextUtils.isEmpty(outSymbol) || TextUtils.isEmpty(inSymbol)) {
            mPresenter.exchangeCoinRule();
            return;
        }
        String outNums = mEtOut.getText().toString().trim();
        //当转出数量为空，则清空转入币种数量
        if (TextUtils.isEmpty(outNums)) {
            mEtIn.setText("");
            return;
        }
        //当转出数量为0，则更新转入币种数量为0
        BigDecimal outDecimal = new BigDecimal(outNums);
        if (outDecimal.doubleValue() == 0) {
            mEtIn.setText("0");
            return;
        }
        //获取汇率
        String tax = mPresenter.getTaxByPair(outSymbol, inSymbol, true);
        //如果还没有获取到汇率，暂不进行转入数据更新
        if (TextUtils.isEmpty(tax)) {
            return;
        }
        //根据汇率计算出和更新转入币种的数量
        BigDecimal taxDecimal = new BigDecimal(tax);
        BigDecimal inDecimal = outDecimal.multiply(taxDecimal).setScale(8, RoundingMode.DOWN);
        mEtIn.setText(StringUtil.handleZero(inDecimal.toString()));
    }

    /**
     * 通过转入币种数量更新转出币种数量
     */
    private void updateOutNumsByInNums() {
        String outSymbol = getOutSymbol();
        String inSymbol = getInSymbol();
        //当兑换信息不正常时则重新拉取兑换信息
        if (TextUtils.isEmpty(outSymbol) || TextUtils.isEmpty(inSymbol)) {
            mPresenter.exchangeCoinRule();
            return;
        }
        String inNums = mEtIn.getText().toString().trim();
        //当转入数量为空，则清空转出币种数量
        if (TextUtils.isEmpty(inNums)) {
            mEtOut.setText("");
            return;
        }
        //当转入数量为0，则更新转出币种数量为0
        BigDecimal inDecimal = new BigDecimal(inNums);
        if (inDecimal.doubleValue() == 0) {
            mEtOut.setText("0");
            return;
        }
        //获取汇率
        String tax = mPresenter.getTaxByPair(outSymbol, inSymbol, true);
        //如果还没有获取到汇率，暂不进行转入数据更新
        if (TextUtils.isEmpty(tax)) {
            return;
        }
        //根据汇率计算出并更新转出币种的数量
        BigDecimal taxDecimal = new BigDecimal(tax);
        BigDecimal outDecimal = inDecimal.divide(taxDecimal, 8, RoundingMode.DOWN);
        mEtOut.setText(StringUtil.handleZero(outDecimal.toString()));
    }

    @OnClick({R.id.tv_out, R.id.tv_in, R.id.tv_confirm})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_out:
                onSelectOutSymbol();
                break;
            case R.id.tv_in:
                onSelectInSymbol();
                break;
            case R.id.tv_confirm:
                onConfirm();
                break;
        }
    }

    /**
     * 确认兑换
     */
    private void onConfirm() {
        String outSymbol = getOutSymbol();
        String inSymbol = getInSymbol();

        if (TextUtils.isEmpty(outSymbol) || TextUtils.isEmpty(inSymbol)) {
            showToast(getString(R.string.get_exchange_info_fail_and_retry_get));
            mPresenter.exchangeCoinRule();
            return;
        }

        //取得对应交易对的兑换信息
        ExchangeRuleBean exchangeRuleBean = mPresenter.getExchangeRuleBeanByPair(mPresenter.getPair(outSymbol, inSymbol));
        //判断是否支持当前用户角色兑换权限
        if (!isSupportExchangeOfRole(exchangeRuleBean)) {
            return;
        }

        String outNumsStr = mEtOut.getText().toString().trim();
        if (TextUtils.isEmpty(outNumsStr)) {
            showToast(getString(R.string.please_enter_the_swap_out_quantity));
            return;
        }

        BigDecimal outNumsDecimal = new BigDecimal(outNumsStr);
        double outNums = outNumsDecimal.doubleValue();
        if (outNums == 0) {
            showToast(getString(R.string.the_swap_out_quantity_is_zero));
            return;
        }

        //判断换出量是否超出限制范围
        BigDecimal outMinVolumeDecimal = new BigDecimal(exchangeRuleBean.getOutMinVolume());
        if (outNums < outMinVolumeDecimal.doubleValue()) {
            showToast(ResourceUtil.getString(R.string.sth_the_commutation_quantity_cannot_be_less_than_nums, outSymbol, StringUtil.handleZero(exchangeRuleBean.getOutMinVolume())));
            return;
        }
        BigDecimal outMaxVolumeDecimal = new BigDecimal(exchangeRuleBean.getOutMaxVolume());
        if (outNums > outMaxVolumeDecimal.doubleValue()) {
            showToast(ResourceUtil.getString(R.string.sth_the_commutation_quantity_cannot_be_greater_than_nums, outSymbol, StringUtil.handleZero(exchangeRuleBean.getOutMaxVolume())));
            return;
        }

        mTvConfirm.setEnabled(false);
        showSpinnerDlg(getString(R.string.change_in_the), false);
        mPresenter.exchangePay(exchangeRuleBean.getOutSymbol(), exchangeRuleBean.getInSymbol(), outNumsStr);
    }

    private boolean isSupportExchangeOfRole(ExchangeRuleBean exchangeRuleBean) {
        if (UserHelper.isSilver()) {//是广告商，并且支持广告商兑换
            boolean isSupportSilver = "1".equals(exchangeRuleBean.getAdvertiserStatus());
            if (isSupportSilver) {
                return true;
            } else {
                showToast(ResourceUtil.getString(R.string.sth_is_not_currently_supported_by_advertisers, exchangeRuleBean.getOutSymbol()));
                return false;
            }
        } else if (UserHelper.isMerchant()) {
            boolean isSupportMerchant = "1".equals(exchangeRuleBean.getMerchantStatus());
            if (isSupportMerchant) {
                return true;
            } else {
                showToast(ResourceUtil.getString(R.string.sth_is_not_currently_supported_by_merchant, exchangeRuleBean.getOutSymbol()));
                return false;
            }
        } else {
            boolean isSupportNormalUser = "1".equals(exchangeRuleBean.getNormalUserStatus());
            if (isSupportNormalUser) {
                return true;
            } else {
                showToast(ResourceUtil.getString(R.string.sth_is_not_currently_supported_by_normal_user, exchangeRuleBean.getOutSymbol()));
                return false;
            }
        }
    }

    private ExchangeSymbolPopupWindow mInSymbolPopupWindow = null;
    private ExchangeSymbolPopupWindow mOutSymbolPopupWindow = null;

    private void onSelectOutSymbol() {
        ArrayList<String> outSymbols = mPresenter.getOutSymbols();

        if (outSymbols.size() == 0) return;

        if (mOutSymbolPopupWindow == null) {
            mOutSymbolPopupWindow = new ExchangeSymbolPopupWindow(this);
            mOutSymbolPopupWindow
                    .setOnSelSymbolListener(new ExchangeSymbolPopupWindow.OnSelSymbolListener() {
                        @Override
                        public void onSelSymbol(String symbol) {
                            updateOutSymbol(symbol);
                        }
                    })
                    .setWidth(DataUtils.dp2px(ExchangeActivity.this, 129))
                    .gravity(Gravity.BOTTOM)
                    .showAnim(new CustomBounceTopEnter())
                    .dismissAnim(new SlideTopExit())
                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            if (mTvOut != null) {
                                mTvOut.setSelected(false);
                            }
                        }
                    });
        }
        mOutSymbolPopupWindow.offset(0, 0)
                .anchorView(mTvOut)
                .setData(outSymbols)
                .setSelItem(mTvOut.getText().toString().trim()).show();
        mTvOut.setSelected(true);
    }

    private void onSelectInSymbol() {

        String outSymbol = getOutSymbol();
        if (TextUtils.isEmpty(outSymbol)) {
            showToast(getString(R.string.get_exchange_info_fail_and_retry_get));
            mPresenter.exchangeCoinRule();
            return;
        }

        ArrayList<String> inSymbols = mPresenter.getInSymbols(outSymbol);

        if (mInSymbolPopupWindow == null) {
            mInSymbolPopupWindow = new ExchangeSymbolPopupWindow(this);
            mInSymbolPopupWindow
                    .setOnSelSymbolListener(new ExchangeSymbolPopupWindow.OnSelSymbolListener() {
                        @Override
                        public void onSelSymbol(String symbol) {
                            updateInSymbol(symbol);
                        }
                    })
                    .setWidth(DataUtils.dp2px(ExchangeActivity.this, 129))
                    .gravity(Gravity.BOTTOM)
                    .showAnim(new CustomBounceTopEnter())
                    .dismissAnim(new SlideTopExit())
                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            if (mTvIn != null) {
                                mTvIn.setSelected(false);
                            }
                        }
                    });
        }
        mInSymbolPopupWindow.offset(0, 0)
                .anchorView(mTvIn)
                .setData(inSymbols)
                .setSelItem(mTvIn.getText().toString().trim()).show();
        mTvIn.setSelected(true);
    }


    @Override
    public void getExchangeCoinRuleSuccess() {
        //获取兑换信息成功，更新转出币种
        ArrayList<String> outSymbols = mPresenter.getOutSymbols();
        updateOutSymbol(outSymbols.size() > 0 ? outSymbols.get(0) : "");
    }

    /**
     * 更新转出币种
     *
     * @param outSymbol 转出币种符号
     */
    private void updateOutSymbol(String outSymbol) {
        if (TextUtils.isEmpty(outSymbol)) return;
        mTvOut.setText(outSymbol);
        //根据情况更新转入币种
        ArrayList<String> inSymbols = mPresenter.getInSymbols(outSymbol);
        String oldInSymbol = getInSymbol();
        updateInSymbol(TextUtils.isEmpty(oldInSymbol) ?
                inSymbols.get(0) : inSymbols.contains(oldInSymbol) ? oldInSymbol : inSymbols.get(0));
    }

    /**
     * 更新转入币种
     *
     * @param inSymbol 转入币种符号
     */
    private void updateInSymbol(String inSymbol) {
        mTvIn.setText(inSymbol);
        //清空输入数据
        mEtOut.setText("");

        String outSymbol = getOutSymbol();
        String pair = mPresenter.getPair(outSymbol, inSymbol);
        //取得对应交易对的兑换信息
        ExchangeRuleBean exchangeRuleBean = mPresenter.getExchangeRuleBeanByPair(pair);
        //填充换出量信息
        mTvChangeTheQuantity.setText(ResourceUtil.getString(R.string.format_change_the_quantity,
                StringUtil.handleZero(exchangeRuleBean.getOutMinVolume()), outSymbol, StringUtil.handleZero(exchangeRuleBean.getOutMaxVolume())));
        //更新兑换说明
        updateExchangeExplain(exchangeRuleBean);
        //请求汇率信息
        mPresenter.requestExchangeTax(outSymbol, inSymbol);
    }

    /**
     * 更新兑换说明
     *
     * @param exchangeRuleBean
     */
    private void updateExchangeExplain(ExchangeRuleBean exchangeRuleBean) {
        StringBuilder sb = new StringBuilder();
        sb.append("2".equals(exchangeRuleBean.getAdvertiserStatus()) ? getString(R.string.adver) : "");
        sb.append("2".equals(exchangeRuleBean.getMerchantStatus()) ?getString(R.string.mercher) : "");
        sb.append("2".equals(exchangeRuleBean.getNormalUserStatus()) ? getString(R.string.normal_userinfo) : "");
        if (TextUtils.isEmpty(sb)) {
            mTvExchangeExplain.setText(R.string.exchange_explain_suffix);
        } else {
            mTvExchangeExplain.setText(String.format(getString(R.string.exchange_explain_template),
                    sb.substring(0, sb.length() - 1), getString(R.string.exchange_explain_suffix)));
        }
    }

    /**
     * 获取汇率成功
     *
     * @param outSymbol 该汇率对应的转出币
     * @param inSymbol  改汇率对应的转入币
     * @param taxValue  汇率值
     */
    @Override
    public void getExchangeTaxSuccess(String outSymbol, String inSymbol, String taxValue) {
        //获取当前页面展示的转入转出币符号
        String curOutSymbol = getOutSymbol();
        String curInSymbol = getInSymbol();
        //当交易队匹配成功时进行汇率数据更新
        if (curOutSymbol.equals(outSymbol) && curInSymbol.equals(inSymbol)) {
            //更新汇率展示
            updateTax(outSymbol, inSymbol, taxValue);
            //更新计算结果
            updateDataCauseOfUpdateTax();
            //更新手续费
            updateFee();
        }
    }

    @Override
    public void exchangePayFail(String errMessage) {
        dismissSpinnerDlg();
        mTvConfirm.setEnabled(true);
        showToast(errMessage);
    }

    @Override
    public void exchangePaySuccess(ExchangeRecordBean exchangeRecordBean) {
        dismissSpinnerDlg();
        Bundle bundle = new Bundle();
        bundle.putSerializable(ExchangeDetailActivity.EXTRA_EXCHANGE_RECORD, exchangeRecordBean);
        $startActivity(ExchangeDetailActivity.class, bundle);

        mEtOut.setText("");//兑换成功后清理数据
        mTvConfirm.setEnabled(true);
    }

    /**
     * 因汇率更新，重新计算换算结果和手续费
     */
    private void updateDataCauseOfUpdateTax() {
        String outNums = mEtOut.getText().toString().trim();
        String inNums = mEtIn.getText().toString().trim();

        //当二者内容都为空，则无需操作
        if (TextUtils.isEmpty(outNums) && TextUtils.isEmpty(inNums)) {
            return;
        }
        //移除输入监听
        mEtOut.removeTextChangedListener(mOutWatcher);
        mEtIn.removeTextChangedListener(mInWatcher);
        //根据输入内容更新换算，优先使用换出币种数量
        if (!TextUtils.isEmpty(outNums)) {
            updateInNumsByOutNums();
        } else {
            updateOutNumsByInNums();
        }
        //重新添加监听
        mEtOut.addTextChangedListener(mOutWatcher);
        mEtIn.addTextChangedListener(mInWatcher);
    }

    /**
     * 更新汇率
     *
     * @param outSymbol 转出币符号
     * @param inSymbol  转入币符号
     * @param taxValue  汇率值
     */
    private void updateTax(String outSymbol, String inSymbol, String taxValue) {
        mTvExchangeRate.setText(ResourceUtil.getString(R.string.template_exchange_example, outSymbol, taxValue, inSymbol));
    }

    /**
     * 更新手续费
     */
    private void updateFee() {

        String outNums = mEtOut.getText().toString().trim();
        if (TextUtils.isEmpty(outNums)) {
            mTvServiceCharge.setText("");
            return;
        }

        String inSymbol = getInSymbol();
        String outSymbol = getOutSymbol();

        //如果获取兑换信息失败则重新获取兑换信息
        if (TextUtils.isEmpty(inSymbol) || TextUtils.isEmpty(outSymbol)) {
            mTvServiceCharge.setText("");
            return;
        }

        //获取汇率信息，如果没有对应的汇率信息，则会重新请求
        String tax = mPresenter.getTaxByPair(outSymbol, inSymbol, false);
        //如果汇率信息为空暂不显示
        if (TextUtils.isEmpty(tax)) {
            mTvServiceCharge.setText("");
            return;
        }
        //获取对应的兑换信息
        ExchangeRuleBean exchangeRuleBean = mPresenter.getExchangeRuleBeanByPair(mPresenter.getPair(outSymbol, inSymbol));
        //去除手续费比率
        String inFeeRate = exchangeRuleBean.getInFeeRate();
        //手续费异常
        if (TextUtils.isEmpty(inFeeRate)) {
            mTvServiceCharge.setText(R.string.exchange_fee_exception);
            return;
        }

        BigDecimal outNumsDecimal = new BigDecimal(outNums);
        BigDecimal taxDecimal = new BigDecimal(tax);
        BigDecimal inFeeRateDecimal = new BigDecimal(inFeeRate);

        BigDecimal feeDecimal = outNumsDecimal.multiply(taxDecimal).multiply(inFeeRateDecimal).setScale(8, RoundingMode.DOWN);

        mTvServiceCharge.setText(String.format("≈ %s %s", StringUtil.handleZero(feeDecimal.toPlainString()), inSymbol));
    }

    @NonNull
    private String getInSymbol() {
        return mTvIn.getText().toString().trim();
    }

    @NonNull
    private String getOutSymbol() {
        return mTvOut.getText().toString().trim();
    }
}
